/**
 * 
 */
package org.swing.utility.jdbc.transaction;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author lqnhu
 *
 */
public class JDBCTransaction implements Transaction {
	private Logger log = LoggerFactory.getLogger(JDBCTransaction.class);
	protected Connection connection;
	protected DataSource dataSource;
	protected TransactionIsolationLevel level;
	protected boolean autoCommit;

	public JDBCTransaction() throws SQLException {
		//this(getDataSource(), null, false);
	}

//	private static DataSource getDataSource(String driver, String url, String user, String password) throws SQLException {
//		try {
//			return DSManager.getDataSource();
//		} catch (Exception e) {
//			throw new SQLException("getDataSource : ", e);
//		}
//	}

	public JDBCTransaction(DataSource ds,
			TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
		dataSource = ds;
		level = desiredLevel;
		autoCommit = desiredAutoCommit;
	}

	public JDBCTransaction(Connection connection) {
		this.connection = connection;
	}

	public Connection getConnection() throws SQLException {
		if (connection == null) {
			openConnection();
		}
		return connection;
	}

	public void commit() throws SQLException {
		if (connection != null && !connection.getAutoCommit()) {
			if (log.isDebugEnabled()) {
				log.debug("Committing JDBC Connection [" + connection + "]");
			}
			connection.commit();
		}
	}

	public void rollback() throws SQLException {
		if (connection != null && !connection.getAutoCommit()) {
			if (log.isDebugEnabled()) {
				log.debug("Rolling back JDBC Connection [" + connection + "]");
			}
			connection.rollback();
		}
	}

	public void close() throws SQLException {
		if (connection != null) {
			resetAutoCommit();
			if (log.isDebugEnabled()) {
				log.debug("Closing JDBC Connection [" + connection + "]");
			}
			connection.close();
		}
	}

	protected void setDesiredAutoCommit(boolean desiredAutoCommit)
			throws SQLException {
		if (connection.getAutoCommit() != desiredAutoCommit) {
			if (log.isDebugEnabled()) {
				log.debug("Setting autocommit to " + desiredAutoCommit
						+ " on JDBC Connection [" + connection + "]");
			}
			connection.setAutoCommit(desiredAutoCommit);
		}
	}

	protected void resetAutoCommit() throws SQLException {
		if (!connection.getAutoCommit()) {
			if (log.isDebugEnabled()) {
				log.debug("Resetting autocommit to true on JDBC Connection ["
						+ connection + "]");
			}
			connection.setAutoCommit(true);
		}
	}

	protected void openConnection() throws SQLException {
		if (log.isDebugEnabled()) {
			log.debug("Opening JDBC Connection");
		}
		connection = dataSource.getConnection();
		if (level != null) {
			connection.setTransactionIsolation(level.getLevel());
		}
		setDesiredAutoCommit(autoCommit);
	}
}
